<template>
    <div class="wh-100% flex flex-col gap-10px">
        <div class="w-full h-70% flex flex-col gap-10px">
            <div class="w-full flex justify-between">
                <!-- 会议室搜索条件筛选 -->
                <div class="flex">
                    <DynamicParam :search-params="searchParams" />
                    <n-button
                        :focusable="false"
                        @click="searchModalvisible = true"
                    >
                        <template #icon>
                            <n-icon :component="List" />
                        </template>
                        筛选
                    </n-button>
                </div>
                <!-- 操作按钮 -->
                <div class="flex gap-10px items-center">
                    <div>
                        第 {{ pagination.page }} 页 / 共
                        {{ Math.ceil(pagination.total / pagination.size) }}页
                    </div>
                    <n-button :focusable="false" @click="handleRefreshRoom">
                        <template #icon>
                            <n-icon :component="RefreshCircle" />
                        </template>
                        刷新
                    </n-button>
                    <n-button
                        ghost
                        type="info"
                        :focusable="false"
                        @click="
                            roomFormvisible = true;
                            roomFormModel = 'create';
                            currentMeetingRoom = null;
                        "
                    >
                        <template #icon>
                            <n-icon :component="Add" />
                        </template>
                        新增
                    </n-button>
                </div>
            </div>
            <!-- 会议室为空结果页 -->
            <div
                v-if="currentMeetingRooms.length === 0"
                class="wh-100% flex-center"
            >
                <n-result
                    status="404"
                    title="暂无会议室"
                    size="huge"
                    description="真是寂寞如雪啊"
                >
                </n-result>
            </div>
            <!-- 会议室表格 -->
            <n-spin
                v-if="currentMeetingRooms.length !== 0"
                :show="loading"
                content-style="height: 100%"
                class="wh-100% overflow-scroll"
            >
                <div class="wh-100% flex overflow-scroll">
                    <RoomTable
                        :model="roomTableModel"
                        :meeting-rooms="currentMeetingRooms"
                        :using-rooms="usingRooms"
                        @next="handleChangePage('next')"
                        @prev="handleChangePage('prev')"
                        @click-item="handleClickRoomItem"
                        @rclick-update="
                            roomFormvisible = true;
                            roomFormModel = 'update';
                        "
                        @rclick-delete="handleDeleteRoom"
                    />
                </div>
            </n-spin>
        </div>
        <div class="w-full h-30%">
            <div class="wh-100% flex gap-16px" v-if="currentMeetingRoom">
                <n-card
                    class="w-55% h-full"
                    content-class="wh-100% flex flex-col"
                >
                    <n-divider>会议室详情</n-divider>
                    <div class="wh-100% overflow-scroll">
                        <RoomDetail :room="currentMeetingRoom" />
                    </div>
                </n-card>
                <n-card
                    class="w-45% h-full"
                    content-class="wh-100% flex flex-col"
                >
                    <n-divider>会议室预约</n-divider>
                    <div class="wh-100% overflow-scroll">
                        <div
                            v-if="currentRoomReservations.length === 0"
                            class="wh-100% flex-center"
                        >
                            <n-empty description="暂无预约" />
                        </div>
                        <n-collapse
                            v-else
                            accordion
                            class="mt-10px"
                            default-expanded-names="1"
                        >
                            <template
                                v-for="(item, index) in currentRoomReservations"
                                :key="index"
                            >
                                <n-collapse-item
                                    :title="`编号-${item.reservationId}`"
                                    :name="`${index + 1}`"
                                >
                                    <n-grid :cols="2" :x-gap="10">
                                        <n-gi>
                                            <n-list hoverable>
                                                <n-list-item>
                                                    <n-thing
                                                        title="预约日期"
                                                        :title-extra="
                                                            new Date(
                                                                item.reserveDate
                                                            ).toLocaleDateString()
                                                        "
                                                    />
                                                </n-list-item>
                                            </n-list>
                                        </n-gi>
                                        <n-gi>
                                            <n-list hoverable>
                                                <n-list-item>
                                                    <n-thing
                                                        title="预约时间"
                                                        :title-extra="`${item.startTime}:00 - ${item.endTime}:00`"
                                                    />
                                                </n-list-item>
                                            </n-list>
                                        </n-gi>
                                    </n-grid>
                                </n-collapse-item>
                            </template>
                        </n-collapse>
                    </div>
                </n-card>
            </div>
            <div v-else class="wh-100% flex-center">
                <n-empty description="这里空空如也哦" size="large" />
            </div>
        </div>

        <!-- 会议室筛选条件弹窗 -->
        <n-modal v-model:show="searchModalvisible">
            <RoomSearch
                :search-params="searchParams"
                @filter-params="handleSearchMeetingRoom"
            />
        </n-modal>
        <!-- 会议室新建编辑抽屉, 内含会议室表单 -->
        <n-drawer v-model:show="roomFormvisible" width="400" placement="right">
            <n-drawer-content>
                <template #header>
                    {{
                        roomFormModel === "create" ? "新建会议室" : "编辑会议室"
                    }}
                </template>
                <RoomForm
                    :model="roomFormModel"
                    :data="currentMeetingRoom"
                    @submit="handleOperateRoom"
                />
            </n-drawer-content>
        </n-drawer>
    </div>
</template>

<script lang="ts" setup>
import { ref, reactive, onMounted } from "vue";
import type {
    MeetingRoom,
    MeetingRoomSearchParams,
    RoomReservations,
} from "@/service/api/types/room";
import { RefreshCircle, Add, List } from "@vicons/ionicons5";
import {
    addMeetingRoom,
    getRoomCounts,
    getUsingRooms,
    getRoomReservations,
    getMeetingRoomList,
    searchMeetingRooms,
    deleteMeetingRoom,
    updateMeetingRoom,
} from "@/service/api/modules/room";
import { processRoomSearchParams } from "@/utils/room";

import RoomForm from "../components/room-form/index.vue";
import RoomTable from "../components/room-table/index.vue";
import RoomSearch from "../components/room-search/index.vue";
import RoomDetail from "../components/room-detail/index.vue";
import DynamicParam from "../components/dynamic-param/index.vue";

const loading = ref(false);
// 显示会议室筛选条件模态框
const searchModalvisible = ref(false);
// 会议室筛选条件
const emptyParams: MeetingRoomSearchParams = {
    name: "",
    area: 0,
    capacity: 0,
    device: {
        speaker: false,
        projector: false,
        internet: false,
    },
    status: null,
    type: null,
};

const searchParams = ref<MeetingRoomSearchParams>(emptyParams);

// 缓存的会议室分页数据
const meetingRooms: Map<number, MeetingRoom[]> = new Map();
// 当前页的会议室信息
const currentMeetingRooms = ref<MeetingRoom[]>([]);
// 当前选中的会议室信息
const currentMeetingRoom = ref<MeetingRoom | null>(null);
// 缓存的会议室的预约信息
const roomReservations: Map<string, RoomReservations[]> = new Map();
// 当前选中的会议室的预约信息
const currentRoomReservations = ref<RoomReservations[]>([]);

// 正在使用的会议室
const usingRooms = ref<string[]>([]);

// 显示会议室新建编辑抽屉
const roomFormvisible = ref(false);
// 会议室表单模式 -> 新建 | 编辑
const roomFormModel = ref<"create" | "update">("create");
// 会议室表格模式 -> 列表 | 搜索
const roomTableModel = ref<"list" | "search">("list");

const pagination = reactive({
    page: 1,
    size: 20,
    total: 0,
});

// 分页获取会议室列表
const getMeetingRooms = async (page: number) => {
    loading.value = true;
    try {
        const res = await getMeetingRoomList({
            page: page,
            size: pagination.size,
        });
        meetingRooms.set(pagination.page, res);
        currentMeetingRooms.value = res;
    } catch (err) {
        window.NMessage.error((err as Error).message);
    } finally {
        loading.value = false;
    }
};

onMounted(async () => {
    try {
        pagination.total = await getRoomCounts();
        if (pagination.total === 0) {
            return;
        }
        getMeetingRooms(pagination.page);
        usingRooms.value = await getUsingRooms();
    } catch (err) {
        window.NMessage.error((err as Error).message);
    }
});

// 搜索符合条件的会议室
const handleSearchMeetingRoom = async (params: MeetingRoomSearchParams) => {
    currentMeetingRoom.value = null;
    searchModalvisible.value = false;
    searchParams.value = params;
    try {
        const params_ = processRoomSearchParams(params);
        if (Object.keys(params_).length === 0) {
            roomTableModel.value = "list";
            getMeetingRooms(pagination.page);
            return;
        }
        pagination.page = 1;
        meetingRooms.clear();
        roomTableModel.value = "search";
        currentMeetingRooms.value = await searchMeetingRooms(params_);
    } catch (err) {
        window.NMessage.error((err as Error).message);
    }
};

// 点击会议室列表项事件
const handleClickRoomItem = async (room: MeetingRoom) => {
    currentMeetingRoom.value = room;
    if (roomReservations.has(room.id!)) {
        currentRoomReservations.value = roomReservations.get(room.id!)!;
        return;
    }
    // 获取该会议室现有的预约信息
    try {
        const reservations = await getRoomReservations(room.id!);
        roomReservations.set(room.id!, reservations);
        currentRoomReservations.value = reservations;
        console.log(currentRoomReservations.value);
    } catch (err) {
        window.NMessage.error((err as Error).message);
    }
};

// 翻页
const handleChangePage = (type: "next" | "prev") => {
    // 如果是第一页或者最后一页就不翻页
    if (
        (pagination.page === 1 && type === "prev") ||
        (pagination.page * pagination.size >= pagination.total &&
            type === "next")
    ) {
        return;
    }
    pagination.page =
        type === "next" ? pagination.page + 1 : pagination.page - 1;
    if (meetingRooms.has(pagination.page)) {
        currentMeetingRooms.value = meetingRooms.get(pagination.page)!;
        return;
    }
    getMeetingRooms(pagination.page);
};

// 刷新当前页面
const handleRefreshRoom = async () => {
    currentMeetingRoom.value = null;
    currentRoomReservations.value = [];
    searchParams.value = emptyParams;
    roomTableModel.value = "list";
    meetingRooms.clear();
    roomReservations.clear();

    getMeetingRooms(pagination.page);
    usingRooms.value = await getUsingRooms();
};

const handleOperateRoom = async (data: MeetingRoom) => {
    try {
        if (roomFormModel.value === "create") {
            await addMeetingRoom(data);
            pagination.total++;
            window.NMessage.success("会议室创建成功");
        } else {
            if (usingRooms.value.includes(data.id!)) {
                window.NMessage.error("会议室正在使用中, 无法编辑");
                return;
            }
            await updateMeetingRoom(data);
            window.NMessage.success("会议室更新成功");
        }
        roomFormvisible.value = false;
        handleRefreshRoom();
    } catch (err) {
        window.NMessage.error((err as Error).message);
    }
};

const handleDeleteRoom = () => {
    window.NDialog.warning({
        title: "提示",
        content: "确定要删除该会议室吗？",
        closable: false,
        positiveText: "确定",
        negativeText: "取消",
        onPositiveClick: async () => {
            try {
                await deleteMeetingRoom(currentMeetingRoom.value!.id!);
                window.NMessage.success("会议室删除成功");
                meetingRooms.clear();
                handleRefreshRoom();
            } catch (err) {
                window.NMessage.error((err as Error).message);
            }
        },
    });
};
</script>

<style scoped>
:deep(.n-divider) {
    margin: 4px;
}
</style>
